import config from "../../config";
import md5 from 'js-md5';

// 全局socket
let socket = null;
// 连接状态
let isConnected = false;
// 当前重连次数
let reconnectCount = 0;
// 最大重连次数
const MAX_RECONNECT_COUNT = 5;
// 重连间隔（毫秒）
const RECONNECT_INTERVAL = 5000;
// 重连定时器
let reconnectTimer = null;
// 是否正在重连
let isReconnecting = false;
// 心跳定时器
let heartbeatTimer = null;
// 心跳间隔（毫秒）
const HEARTBEAT_INTERVAL = 30000;
// 连接超时时间
const CONNECTION_TIMEOUT = 10000;
// 连接超时定时器
let connectionTimeoutTimer = null;
// 消息队列（连接断开时缓存消息）
let messageQueue = [];
// 事件监听器映射
let eventListeners = new Map();

/**
 * 生成随机字符串
 */
function generateNonce(length = 16) {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  let result = '';
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return result;
}

/**
 * 生成签名
 */
function generateSignature(timestamp, nonce, uid, secretKey = '') {
  if (!secretKey) {
    secretKey = config.wsSecretKey || 'default_secret_key';
  }
  
  const params = { timestamp, nonce, uid, secretKey };
  const signString = Object.keys(params)
    .sort()
    .map(key => `${key}=${params[key]}`)
    .join('&');
  
  return md5(signString);
}

/**
 * 验证签名
 */
function verifySignature(timestamp, nonce, uid, signature, secretKey = '') {
  if (!timestamp || !nonce || !uid || !signature) {
    return false;
  }
  
  const now = Date.now();
  const timestampNum = parseInt(timestamp);
  const timeout = config.wsAuthTimeout || 30000;
  
  if (now - timestampNum > timeout) {
    console.warn('WebSocket验签超时');
    return false;
  }
  
  const expectedSignature = generateSignature(timestamp, nonce, uid, secretKey);
  return expectedSignature === signature;
}

/**
 * 获取验签参数
 */
function getAuthParams(uid) {
  const timestamp = Date.now().toString();
  const nonce = generateNonce();
  const signature = md5("timestamp="+timestamp+"&nonce="+nonce+"&01e553a3697a0479bac95466cea61487e1dba680").toString();

  return { timestamp, nonce, signature };
}

/**
 * 启动心跳检测
 */
function startHeartbeat(uid) {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
  }
  
  heartbeatTimer = setInterval(() => {
    if (isConnected) {
      sendHeartbeatMessage(uid);
    }
  }, HEARTBEAT_INTERVAL);
}

/**
 * 停止心跳检测
 */
function stopHeartbeat() {
  if (heartbeatTimer) {
    clearInterval(heartbeatTimer);
    heartbeatTimer = null;
  }
}

/**
 * 处理消息队列
 */
function processMessageQueue() {
  if (messageQueue.length > 0 && isConnected) {
    console.log(`处理消息队列，共${messageQueue.length}条消息`);
    const queue = [...messageQueue];
    messageQueue = [];
    
    queue.forEach(({ type, message, uid, resolve, reject }) => {
      sendMessage(type, message, uid)
        .then(resolve)
        .catch(reject);
    });
  }
}

/**
 * 触发事件
 */
function emitEvent(eventName, data) {
  if (eventListeners.has(eventName)) {
    eventListeners.get(eventName).forEach(callback => {
      try {
        callback(data);
      } catch (error) {
        console.error(`事件监听器执行错误 [${eventName}]:`, error);
      }
    });
  }
}

// 初始化WebSocket
export function initWebSocket(uid, isReconnect = false) {
  return new Promise((resolve, reject) => {
    if (socket) {
      closeWebSocket();
    }

    if (isReconnect) {
      console.log(`WebSocket第${reconnectCount}次重连尝试`);
    } else {
      reconnectCount = 0;
    }

    const authParams = getAuthParams(uid);
    // console.log('WebSocket验签参数:', authParams);

    connectionTimeoutTimer = setTimeout(() => {
      if (!isConnected) {
        console.error('WebSocket连接超时');
        reject(new Error('连接超时'));
        closeWebSocket();
      }
    }, CONNECTION_TIMEOUT);

    // 创建标准WebSocket连接
    try {
      const wsUrl = `${config.wsUrl}?timestamp=${authParams.timestamp}&nonce=${authParams.nonce}&signature=${authParams.signature}`;
      socket = new WebSocket(wsUrl);
      
      console.log("WebSocket连接创建成功", wsUrl);
    } catch (err) {
      console.error("WebSocket连接创建失败", err);
      clearTimeout(connectionTimeoutTimer);
      reject(err);
      return;
    }

    // 添加标准WebSocket事件监听器
    socket.onopen = () => {
      console.log("WebSocket连接已打开，状态为 OPEN");
      clearTimeout(connectionTimeoutTimer);
      isConnected = true;
      isReconnecting = false;
      if (reconnectTimer) {
        clearTimeout(reconnectTimer);
        reconnectTimer = null;
      }
      
      // startHeartbeat(uid);
      processMessageQueue();
      emitEvent('connected', { uid, timestamp: Date.now() });
      resolve(socket);
    };

    socket.onclose = () => {
      console.log("WebSocket连接已关闭");
      isConnected = false;
      stopHeartbeat();
      emitEvent('disconnected', { timestamp: Date.now() });
    };

    socket.onerror = (err) => {
      console.error("WebSocket连接错误", err);
      isConnected = false;
      stopHeartbeat();
      clearTimeout(connectionTimeoutTimer);
      emitEvent('error', { error: err, timestamp: Date.now() });
      
      if (!isReconnect) {
        reject(err);
      }
    };

    socket.onmessage = (res) => {
      try {
        let data = JSON.parse(res.data);
        
        if (data.auth) {
          const { timestamp, nonce, uid: msgUid, signature } = data.auth;
          if (!verifySignature(timestamp, nonce, msgUid, signature)) {
            console.warn('WebSocket消息验签失败，忽略此消息');
            return;
          }
        }
        
        let type = data.type || data.data;
        emitEvent('message', { type, data, timestamp: Date.now() });
        
        switch (type) {
          case "heartbeat":
            break;
          case "timeout":
            scheduleReconnect(uid);
            break;
          case "error":
            emitEvent('serverError', { data, timestamp: Date.now() });
            break;
          case "auth_failed":
            console.error('WebSocket验签失败，关闭连接');
            emitEvent('authFailed', { data, timestamp: Date.now() });
            closeWebSocket();
            break;
          case "toucunCount":
            try {
              const priceData = JSON.parse(data.msg);
              emitEvent('statisticsUpdate', { data: priceData, timestamp: Date.now() });
            } catch (parseError) {
              console.error('解析价格数据失败:', parseError);
              emitEvent('statisticsUpdate', { type: 'raw', data: data.msg, timestamp: Date.now() });
            }
            break;
          case "MATERIAL_PRICE":
            try {
              const priceData = JSON.parse(data.msg);
              emitEvent('materialPriceUpdate', { data: priceData, timestamp: Date.now() });
            } catch (parseError) {
              console.error('解析价格数据失败:', parseError);
              emitEvent('materialPriceUpdate', { type: 'raw', data: data.msg, timestamp: Date.now() });
            }
            break;
          default:
            emitEvent('customMessage', { type, data, timestamp: Date.now() });
            break;
        }
      } catch (error) {
        console.error('解析WebSocket消息失败:', error);
        emitEvent('parseError', { error, rawData: res.data, timestamp: Date.now() });
      }
    };
  });
}

/**
 * 重连调度函数
 */
export function scheduleReconnect(uid) {
  if (isReconnecting || reconnectCount >= MAX_RECONNECT_COUNT) {
    if (reconnectCount >= MAX_RECONNECT_COUNT) {
      console.error(`已达到最大重连次数 ${MAX_RECONNECT_COUNT}，停止重连`);
      emitEvent('maxReconnectReached', { count: reconnectCount, timestamp: Date.now() });
    }
    return;
  }

  isReconnecting = true;
  reconnectCount++;

  console.log(`${RECONNECT_INTERVAL}ms后进行第${reconnectCount}次重连`);
  emitEvent('reconnecting', { count: reconnectCount, timestamp: Date.now() });

  reconnectTimer = setTimeout(() => {
    console.log("开始执行重连...");
    initWebSocket(uid, true).catch((err) => {
      console.error("重连失败:", err);
      isReconnecting = false;
      emitEvent('reconnectFailed', { error: err, count: reconnectCount, timestamp: Date.now() });
    });
  }, RECONNECT_INTERVAL);
}

/**
 * 发送消息基础方法
 */
export function sendMessage(type, message, uid = '') {
  return new Promise((resolve, reject) => {
    if (!isWebSocketConnected()) {
      messageQueue.push({ type, message, uid, resolve, reject });
      console.log(`WebSocket未连接，消息已加入队列，当前队列长度: ${messageQueue.length}`);
      return;
    }
    
    try {
      const timestamp = Date.now().toString();
      const nonce = generateNonce(8);
      const messageSignature = generateSignature(timestamp, nonce, uid);
      
      const data = JSON.stringify({
        type: type,
        message: message,
        auth: {
          timestamp: timestamp,
          nonce: nonce,
          signature: messageSignature,
          uid: uid
        }
      });
      
      try {
        socket.send(data);
        resolve();
      } catch (err) {
        console.error('消息发送失败', err);
        reject(err);
      }
    } catch (error) {
      console.error("发送消息时出错", error);
      reject(error);
    }
  });
}

// 检查连接状态
export function isWebSocketConnected() {
  return isConnected && socket;
}

// 关闭连接
export function closeWebSocket() {
  if (socket) {
    socket.close();
    socket = null;
    isConnected = false;
  }
  
  isReconnecting = false;
  if (reconnectTimer) {
    clearTimeout(reconnectTimer);
    reconnectTimer = null;
  }
  
  stopHeartbeat();
  
  if (connectionTimeoutTimer) {
    clearTimeout(connectionTimeoutTimer);
    connectionTimeoutTimer = null;
  }
  
  emitEvent('closed', { timestamp: Date.now() });
}

/**
 * 发送心跳消息
 */
export function sendHeartbeatMessage(uid) {
  sendMessage("heartbeat", {
    from_uid: uid,
    to_uid: 0,
    line_id: 0,
    message_type: "text",
    message_content: "ping",
  }, uid);
}

/**
 * 推送坐标
 */
export function pushLocation(uid, phone, avatar, longitude, latitude) {
  sendMessage("push_location", {
    from_uid: uid,
    phone: phone,
    avatar: avatar,
    longitude: longitude,
    latitude: latitude,
  }, uid);
}

/**
 * 拉取坐标
 */
export function pullLocation(uids, uid) {
  sendMessage("pull_location", {
    uids: uids,
  }, uid);
}

/**
 * 发送文本消息
 */
export function sendTextMessage(
  from_uid,
  to_uid,
  line_id,
  message_content,
  message_type = "text"
) {
  sendMessage("text", {
    from_uid: from_uid,
    to_uid: to_uid,
    line_id: line_id,
    message_type: message_type,
    message_content: message_content,
  }, from_uid);
}

/**
 * 获取socket对象
 */
export function getSocket() {
  return socket;
}

/**
 * 获取当前连接状态
 */
export function getConnectionStatus() {
  return isConnected;
}

/**
 * 获取当前重连次数
 */
export function getReconnectCount() {
  return reconnectCount;
}

/**
 * 手动重连
 */
export function manualReconnect(uid) {
  console.log('手动重连WebSocket');
  closeWebSocket();
  reconnectCount = 0;
  isReconnecting = false;
  return initWebSocket(uid, false);
}

/**
 * 验证WebSocket连接的有效性
 */
export function validateConnection() {
  if (!isConnected || !socket) {
    return false;
  }
  return true;
}

/**
 * 添加事件监听器
 */
export function addEventListener(eventName, callback) {
  if (!eventListeners.has(eventName)) {
    eventListeners.set(eventName, []);
  }
  eventListeners.get(eventName).push(callback);
}

/**
 * 移除事件监听器
 */
export function removeEventListener(eventName, callback) {
  if (!eventListeners.has(eventName)) {
    return;
  }
  
  if (callback) {
    const listeners = eventListeners.get(eventName);
    const index = listeners.indexOf(callback);
    if (index > -1) {
      listeners.splice(index, 1);
    }
  } else {
    eventListeners.delete(eventName);
  }
}

/**
 * 获取消息队列长度
 */
export function getMessageQueueLength() {
  return messageQueue.length;
}

/**
 * 清空消息队列
 */
export function clearMessageQueue() {
  messageQueue = [];
}

/**
 * 获取WebSocket统计信息
 */
export function getWebSocketStats() {
  return {
    isConnected,
    reconnectCount,
    isReconnecting,
    messageQueueLength: messageQueue.length,
    eventListenersCount: eventListeners.size,
    timestamp: Date.now()
  };
}
